home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DTP / DTP_TEX / H219.ZIP / DVIPSSRC.ZIP / dvips / dvips.c < prev    next >
C/C++ Source or Header  |  1993-05-22  |  35KB  |  1,065 lines

  1. /*
  2.  *   This is the main routine.
  3.  */
  4. #ifndef DEFRES
  5. #define DEFRES (300)
  6. #endif
  7.  
  8. #include "dvips.h" /* The copyright notice there is included too! */
  9. #ifndef SYSV
  10. extern char *strtok() ; /* some systems don't have this in strings.h */
  11. #endif
  12. #ifdef VMS
  13. #define GLOBAL globaldef
  14. #include climsgdef
  15. #include ctype
  16. #include descrip
  17. #endif
  18. /*
  19.  *   First we define some globals.
  20.  */
  21. #ifdef VMS
  22.     static char ofnme[252],infnme[252],pap[40],thh[20];
  23. #endif
  24. fontdesctype *fonthead ;      /* list of all fonts mentioned so far */
  25. fontdesctype *curfnt ;        /* the currently selected font */
  26. sectiontype *sections ;       /* sections to process document in */
  27. Boolean manualfeed ;          /* manual feed? */
  28. Boolean compressed ;          /* compressed? */
  29. Boolean safetyenclose ;
  30.                           /* enclose in save/restore for stupid spoolers? */
  31. Boolean removecomments = 1 ;  /* remove comments from included PS? */
  32. Boolean nosmallchars ;        /* disable small char optimization for X4045? */
  33. Boolean cropmarks ;           /* add cropmarks? */
  34. Boolean abspage = 0 ;         /* are page numbers absolute? */
  35. Boolean tryepsf = 0 ;         /* should we try to make it espf? */
  36. Boolean secure = 0 ;          /* make safe for suid */
  37. int collatedcopies = 1 ;      /* how many collated copies? */
  38. int sectioncopies = 1 ;       /* how many times to repeat each section? */
  39. integer pagecopies = 1 ;          /* how many times to repeat each page? */
  40. shalfword linepos = 0 ;       /* where are we on the line being output? */
  41. integer maxpages ;            /* the maximum number of pages */
  42. Boolean notfirst, notlast ;   /* true if a first page was specified */
  43. Boolean evenpages, oddpages ; /* true if doing only even/only odd pages */
  44. Boolean pagelist ;            /* true if using page ranges */
  45. Boolean sendcontrolD ;        /* should we send a control D at end? */
  46. integer firstpage ;           /* the number of the first page if specified */
  47. integer lastpage ;
  48. integer firstseq ;
  49. integer lastseq ;
  50. integer hpapersize, vpapersize ; /* horizontal and vertical paper size */
  51. integer hoff, voff ;          /* horizontal and vertical offsets */
  52. integer maxsecsize ;          /* the maximum size of a section */
  53. integer firstboploc ;         /* where the first bop is */
  54. Boolean sepfiles ;            /* each section in its own file? */
  55. int numcopies ;               /* number of copies of each page to print */
  56. char *oname ;                 /* output file name */
  57. char *iname ;                 /* dvi file name */
  58. char *fulliname ;             /* same, with current working directory */
  59. char *strings ;               /* strings for program */
  60. char *nextstring, *maxstring ; /* string pointers */
  61. FILE *dvifile, *bitfile ;     /* dvi and output files */
  62. quarterword *curpos ;        /* current position in virtual character packet */
  63. quarterword *curlim ;         /* final byte in virtual character packet */
  64. fontmaptype *ffont ;          /* first font in current frame */
  65. real conv ;                   /* conversion ratio, pixels per DVI unit */
  66. real vconv ;                  /* conversion ratio, pixels per DVI unit */
  67. real alpha ;                  /* conversion ratio, DVI unit per TFM unit */
  68. integer mag ;                 /* the magnification of this document */
  69. integer num, den ;            /* the numerator and denominator */
  70. int overridemag ;             /* substitute for mag value in DVI file? */
  71. int actualdpi = DEFRES ;      /* the actual resolution of the printer */
  72. int vactualdpi = DEFRES ;     /* the actual resolution of the printer */
  73. int maxdrift ;                /* max pixels away from true rounded position */
  74. int vmaxdrift ;               /* max pixels away from true rounded position */
  75. char *paperfmt ;              /* command-line paper format */
  76. int landscape = 0 ;           /* landscape mode */
  77. integer fontmem ;             /* memory remaining in printer */
  78. integer pagecount ;           /* page counter for the sections */
  79. integer pagenum ;             /* the page number we currently look at */
  80. long bytesleft ;              /* number of bytes left in raster */
  81. quarterword *raster ;         /* area for raster manipulations */
  82. integer hh, vv ;              /* horizontal and vertical pixel positions */
  83. char *tfmpath = TFMPATH ;     /* pointer to directories for tfm files */
  84. char *pkpath = PKPATH ;       /* pointer to directories for pk files */
  85. char *vfpath = VFPATH ;       /* pointer to directories for vf files */
  86. char *figpath = FIGPATH ;     /* pointer to directories for figure files */
  87. char *headerpath = HEADERPATH ; /* pointer to directories for header files */
  88. char *configpath = CONFIGPATH ; /* where to find config files */
  89. char *infont ;                /* is the file we are downloading a font? */
  90. #ifndef PICTPATH
  91. #ifndef __THINK__
  92. #define PICTPATH "."
  93. #else
  94. #define PICTPATH ":"
  95. #endif
  96. #endif
  97. char *pictpath = PICTPATH ;   /* where IFF/etc. pictures are found */
  98. #ifdef SEARCH_SUBDIRECTORIES
  99. char *fontsubdirpath = FONTSUBDIRPATH ;
  100. #endif
  101. #ifdef FONTLIB
  102. char *flipath = FLIPATH ;     /* pointer to directories for fli files */
  103. char *fliname = FLINAME ;     /* pointer to names of fli files */
  104. #endif
  105. integer swmem ;               /* font memory in the PostScript printer */
  106. int quiet ;                   /* should we only print errors to stderr? */
  107. int filter ;                  /* act as filter default output to stdout,
  108.                                                default input to stdin? */
  109. int prettycolumn ;            /* the column we are at when running pretty */
  110. int gargc ;                   /* global argument count */
  111. char **gargv ;                /* global argument vector */
  112. int totalpages = 0 ;          /* total number of pages */
  113. Boolean reverse ;             /* are we going reverse? */
  114. Boolean usesPSfonts ;         /* do we use local PostScript fonts? */
  115. Boolean usesspecial ;         /* do we use \special? */
  116. Boolean headers_off ;         /* do we send headers or not? */
  117. Boolean usescolor ;           /* IBM: color - do we use colors? */
  118. char *headerfile ;            /* default header file */
  119. char *warningmsg ;            /* a message to write, if set in config file */
  120. Boolean multiplesects ;       /* more than one section? */
  121. Boolean disablecomments ;     /* should we suppress any EPSF comments? */
  122. char *printer ;               /* what printer to send this to? */
  123. char *mfmode ;                /* default MF mode */
  124. frametype frames[MAXFRAME] ;  /* stack for virtual fonts */
  125. fontdesctype *baseFonts[256] ; /* base fonts for dvi file */
  126. integer pagecost;               /* memory used on the page being prescanned */
  127. int delchar;                    /* characters to delete from prescanned page */
  128. integer fsizetol;               /* max dvi units error for psfile font sizes */
  129. Boolean includesfonts;          /* are fonts used in included psfiles? */
  130. fontdesctype *fonthd[MAXFONTHD];/* list headers for included fonts of 1 name */
  131. int nextfonthd;                 /* next unused fonthd[] index */
  132. char xdig[256];                 /* table for reading hexadecimal digits */
  133. char banner[] = BANNER ;        /* our startup message */
  134. Boolean noenv = 0 ;             /* ignore PRINTER envir variable? */
  135. Boolean dopprescan = 0 ;        /* do we do a scan before the prescan? */
  136. integer lastheadermem ;         /* how much mem did the last header require? */
  137. extern int dontmakefont ;
  138. struct papsiz *papsizes ;       /* all available paper size */
  139. int headersready ;              /* ready to check headers? */
  140. #if defined MSDOS || defined OS2
  141. char *mfjobname = NULL;         /* name of mfjob file if given */
  142. FILE *mfjobfile = NULL;         /* mfjob file for font making instructions */
  143. #endif
  144. #ifdef DEBUG
  145. integer debug_flag = 0;
  146. #endif /* DEBUG */
  147. char queryline[256];                /* interactive query of options */
  148. int qargc;
  149. char *qargv[32];
  150. char queryoptions;
  151. /*
  152.  *   This routine calls the following externals:
  153.  */
  154. extern void outbangspecials() ;
  155. extern void prescanpages() ;
  156. extern void pprescanpages() ;
  157. extern void initprinter() ;
  158. extern void cleanprinter() ;
  159. extern void dosection() ;
  160. extern void getdefaults() ;
  161. extern void cmdout() ;
  162. extern void numout() ;
  163. extern void initcolor() ;
  164. extern int add_header() ;
  165. extern int ParsePages() ;
  166. extern void checkenv() ;
  167. extern void getpsinfo(), revpslists() ;
  168. #ifdef FONTLIB
  169. extern void fliload() ;
  170. #endif
  171. #ifdef __THINK__
  172. int dcommand(char ***);
  173. #endif
  174.  
  175. /* Declare the routine to get the current working directory.  */
  176.  
  177. #ifndef IGNORE_CWD
  178. #ifndef HAVE_GETCWD
  179. extern char *getwd (); /* said to be faster than getcwd (SunOS man page) */
  180. #define getcwd(b, len)  getwd(b) /* used here only when b nonnull */
  181. #else
  182. #ifdef ANSI
  183. extern char *getcwd (char *, int);
  184. #else
  185. extern char *getcwd ();
  186. #endif /* not ANSI */
  187. #endif /* not HAVE_GETWD */
  188. #if defined(SYSV) || defined(VMS) || defined(MSDOS)
  189. #define MAXPATHLEN (256)
  190. #else
  191. #include <sys/param.h>          /* for MAXPATHLEN */
  192. #endif
  193. #endif /* not IGNORE_CWD */
  194.  
  195. static char *helparr[] = {
  196. #ifndef VMCMS
  197. "    Usage: dvips [options] filename[.dvi]",
  198. #else
  199. "    VM/CMS Usage:",
  200. "           dvips fname [ftype [fmode]] [options]",
  201. "or",
  202. "           dvips fname[.ftype[.fmode]] [options]",
  203. #endif
  204. "a*  Conserve memory, not time      y # Multiply by dvi magnification",
  205. "b # Page copies, for posters e.g.  A   Print only odd (TeX) pages",
  206. "c # Uncollated copies              B   Print only even (TeX) pages",
  207. "d # Debugging                      C # Collated copies",
  208. "e # Maxdrift value                 D # Resolution",
  209. "f*  Run as filter                  E*  Try to create EPSF",
  210. "h f Add header file                F*  Send control-D at end",
  211. "i*  Separate file per section      K*  Pull comments from inclusions",
  212. "k*  Print crop marks               M*  Don't make fonts",
  213. "l # Last page                      N*  No structured comments",
  214. "m*  Manual feed                    O c Set/change paper offset",
  215. #ifdef OS2
  216. "n # Maximum number of pages        P s Load $s.cfg",
  217. #else
  218. "n # Maximum number of pages        P s Load config.$s",
  219. #endif
  220. "o f Output file                    R   Run securely",
  221. "p # First page                     S # Max section size in pages",
  222. "q*  Run quietly                    T c Specify desired page size",
  223. "r*  Reverse order of pages         U*  Disable string param trick",
  224. "s*  Enclose output in save/restore X # Horizontal resolution",
  225. "t s Paper format                   Y # Vertical resolution",
  226. "x # Override dvi magnification     Z*  Compress bitmap fonts",
  227. /* "-   Interactive query of options", */
  228. "    # = number   f = file   s = string  * = suffix, `0' to turn off",
  229. "    c = comma-separated dimension pair (e.g., 3.2in,-32.1cm)", 0} ;
  230. void help() {
  231.    char **p ;
  232.    for (p=helparr; *p; p++)
  233.       fprintf(stderr, " %s\n", *p) ;
  234. }
  235. /*
  236.  *   This error routine prints an error message; if the first
  237.  *   character is !, it aborts the job.
  238.  */
  239. static char *progname ;
  240. void
  241. error(s)
  242.         char *s ;
  243. {
  244.    extern void exit() ;
  245.  
  246.    if (prettycolumn > 0)
  247.         fprintf(stderr,"\n");
  248.    prettycolumn = 0;
  249.    (void)fprintf(stderr, "%s: %s\n", progname, s) ;
  250.    if (*s=='!') {
  251.       if (bitfile != NULL) {
  252.          cleanprinter() ;
  253.       }
  254.       exit(1) ; /* fatal */
  255.    }
  256. }
  257. /*
  258.  *   This is our malloc that checks the results.  We debug the
  259.  *   allocations but not the frees, since memory fragmentation
  260.  *   might be such that we can never use the free'd memory and
  261.  *   it's wise to be conservative.  The only real place we free
  262.  *   is when repacking *huge* characters anyway.
  263.  */
  264. #ifdef DEBUG
  265. static integer totalalloc = 0 ;
  266. #endif
  267. char *mymalloc(n)
  268. integer n ;
  269. {
  270.    char *p ;
  271.  
  272. #ifdef SMALLMALLOC
  273.    if (n > 65500L)
  274.       error("! can't allocate more than 64K!") ;
  275. #endif
  276.    if (n <= 0) /* catch strange 0 mallocs in flib.c without breaking code */
  277.       n = 1 ;
  278. #ifdef DEBUG
  279.    totalalloc += n ;
  280.    if (dd(D_MEM)) {
  281. #ifdef SHORTINT
  282.       fprintf(stderr, "Alloc %ld\n", n) ;
  283. #else
  284.       fprintf(stderr, "Alloc %d\n", n) ;
  285. #endif
  286.    }
  287. #endif
  288.    p = malloc(n) ;
  289.    if (p == NULL)
  290.       error("! no memory") ;
  291.    return p ;
  292. }
  293. void
  294. morestrings() {
  295.    strings = mymalloc((integer)STRINGSIZE) ;
  296.    nextstring = strings ;
  297.    maxstring = strings + STRINGSIZE - 200 ;
  298.    *nextstring++ = 0 ;
  299. }
  300. void
  301. checkstrings() {
  302.    if (nextstring - strings > STRINGSIZE / 2)
  303.       morestrings() ;
  304. }
  305. /*
  306.  *   Initialize sets up all the globals and data structures.
  307.  */
  308. void
  309. initialize()
  310. {
  311.    int i;
  312.    char *s;
  313.  
  314.    nextfonthd = 0;
  315.    for (i=0; i<256; i++)
  316.       xdig[i] = 0;
  317.    i = 0;
  318.    for (s="0123456789ABCDEF"; *s!=0; s++)
  319.       xdig[(int)*s] = i++;
  320.    i = 10;
  321.    for (s="abcdef"; *s!=0; s++)
  322.       xdig[(int)*s] = i++;
  323.    morestrings() ;
  324.    maxpages = 100000 ;
  325.    numcopies = 1 ;
  326.    iname = fulliname = strings ;
  327.    bitfile = NULL ;
  328.    bytesleft = 0 ;
  329.    swmem = SWMEM ;
  330.    oname = OUTPATH ;
  331.    sendcontrolD = 0 ;
  332.    multiplesects = 0 ;
  333.    disablecomments = 0 ;
  334.    maxdrift = -1 ;
  335.    vmaxdrift = -1 ;
  336. }
  337. /*
  338.  *   This routine copies a string into the string `pool', safely.
  339.  */
  340. char *
  341. newstring(s)
  342.    char *s ;
  343. {
  344.    int l ;
  345.  
  346.    if (s == NULL)
  347.       return(NULL) ;
  348.    l = strlen(s) ;
  349.    if (nextstring + l >= maxstring)
  350.       morestrings() ;
  351.    if (nextstring + l >= maxstring)
  352.       error("! out of string space") ;
  353.    (void)strcpy(nextstring, s) ;
  354.    s = nextstring ;
  355.    nextstring += l + 1 ;
  356.    return(s) ;
  357. }
  358. void newoutname() {
  359.    static int seq = 0 ;
  360.    static char *seqptr = 0 ;
  361.    char *p ;
  362.  
  363.    if (oname == 0 || *oname == 0)
  364.       error("! need an output file name to specify separate files") ;
  365.    if (*oname != '!') {
  366.       if (seqptr == 0) {
  367.          oname = newstring(oname) ;
  368.          seqptr = 0 ;
  369.          for (p = oname; *p; p++)
  370.             if (*p == '.')
  371.                seqptr = p + 1 ;
  372.          if (seqptr == 0)
  373.             seqptr = p ;
  374.          nextstring += 5 ; /* make room for the number, up to five digits */
  375.       }
  376.       sprintf(seqptr, "%03d", ++seq) ;
  377.    }
  378. }
  379. /*
  380.  *   This routine reverses a list, where a list is defined to be any
  381.  *   structure whose first element is a pointer to another such structure.
  382.  */
  383. VOID *revlist(p)
  384. VOID *p ;
  385. {
  386.    struct list {
  387.       struct list *next ;
  388.    } *pp = (struct list *)p, *qq = 0, *tt ;
  389.  
  390.    while (pp) {
  391.       tt = pp->next ;
  392.       pp->next = qq ;
  393.       qq = pp ;
  394.       pp = tt ;
  395.    }
  396.    return (VOID *)qq ;
  397. }
  398. /* this asks for a new set of arguments from the command line */
  399. void
  400. queryargs()
  401. {
  402.    fputs("Options: ",stdout);
  403.    fgets(queryline,256,stdin);
  404.    qargc=1;
  405.    if ( (qargv[1] = strtok(queryline," \n")) != (char *)NULL ) {
  406.       qargc=2;
  407.       while ( ((qargv[qargc] = strtok((char *)NULL," \n")) != (char *)NULL)
  408.             && (qargc < 31) )
  409.          qargc++;
  410.    }
  411.    qargv[qargc] = (char *)NULL;
  412. }
  413.  
  414. /*
  415.  *   Finally, our main routine.
  416.  */
  417. extern void handlepapersize() ;
  418. #ifdef VMS
  419. main()
  420. #else
  421. void main(argc, argv)
  422.         int argc ;
  423.         char *argv[] ;
  424. #endif
  425. {
  426.    extern void exit() ;
  427.    int i, lastext = -1 ;
  428. #ifdef MVSXA
  429.    int firstext = -1 ;
  430. #endif
  431.    register sectiontype *sects ;
  432.  
  433. #ifdef __THINK__
  434.    argc = dcommand(&argv) ; /* do I/O stream redirection */
  435. #endif
  436. #ifdef VMS        /* Grab the command-line buffer */
  437.    short len_arg;
  438.    $DESCRIPTOR( verb_dsc, "DVIPS ");    /* assume the verb is always DVIPS */
  439.    struct dsc$descriptor_d temp_dsc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_D, 0};
  440.  
  441.    progname = &thh[0] ;
  442.    strcpy(progname,"DVIPS%ERROR");
  443.  
  444.    lib$get_foreign( &temp_dsc, 0, &len_arg, 0);    /* Get the command line */
  445.    str$prefix(&temp_dsc, &verb_dsc);        /* prepend the VERB     */
  446.    len_arg += verb_dsc.dsc$w_length;        /* update the length    */
  447.    temp_dsc.dsc$a_pointer[len_arg] = '\0';    /* terminate the string */
  448.    gargv = &temp_dsc.dsc$a_pointer;        /* point to the buffer  */
  449.    gargc = 1 ;                    /* only one big argv    */
  450. #else
  451.    progname = argv[0] ;
  452.    gargv = argv ;
  453.    gargc = argc ;
  454. /* we sneak a look at the first arg in case it's debugging */
  455. #ifdef DEBUG
  456.    if (argc > 1 && strncmp(argv[1], "-d", 2)==0) {
  457.       if (argv[1][2]==0) {
  458.          if (sscanf(argv[2], "%d", &debug_flag)==0)
  459.             debug_flag = 0 ;
  460.       } else {
  461.          if (sscanf(argv[1]+2, "%d", &debug_flag)==0)
  462.             debug_flag = 0 ;
  463.       }
  464.    }
  465. #endif
  466. #endif
  467.    initialize() ;
  468.    checkenv(0) ;
  469.    getdefaults(CONFIGFILE) ;
  470.    getdefaults((char *)0) ;
  471. /*
  472.  *   This next whole big section of code is straightforward; we just scan
  473.  *   the options.  An argument can either immediately follow its option letter
  474.  *   or be separated by spaces.  Any argument not preceded by '-' and an
  475.  *   option letter is considered a file name; the program complains if more
  476.  *   than one file name is given, and uses stdin if none is given.
  477.  */
  478. #ifdef VMS
  479. vmscli();
  480. #else
  481.    queryoptions = 0;
  482.    do
  483.    {
  484.       for (i=1; i<argc; i++) {
  485.          if (*argv[i]=='-') {
  486.             char *p=argv[i]+2 ;
  487.             char c=argv[i][1] ;
  488.             switch (c) {
  489. case '-':
  490.                queryoptions = 1;
  491.                break;
  492. case 'a':
  493.                dopprescan = (*p != '0') ;
  494.                break ;
  495. case 'b':
  496.                if (*p == 0 && argv[i+1])
  497.                   p = argv[++i] ;
  498.                if (sscanf(p, "%d", &pagecopies)==0)
  499.                   error("! Bad number of page copies option (-b).") ;
  500.                if (pagecopies < 1 || pagecopies > 1000)
  501.                   error("! can only print one to a thousand page copies") ;
  502.                break ;
  503. case 'c' :
  504.                if (*p == 0 && argv[i+1])
  505.                   p = argv[++i] ;
  506.                if (sscanf(p, "%d", &numcopies)==0)
  507.                   error("! Bad number of copies option (-c).") ;
  508.                break ;
  509. case 'd' :
  510. #ifdef DEBUG
  511.                if (*p == 0 && argv[i+1])
  512.                   p = argv[++i];
  513.                if (sscanf(p, "%d", &debug_flag)==0)
  514.                   error("! Bad debug option (-d).");
  515.                break;
  516. #else
  517.                error("not compiled in debug mode") ;
  518.                break ;
  519. #endif /* DEBUG */
  520. case 'e' :
  521.                if (*p == 0 && argv[i+1])
  522.                   p = argv[++i] ;
  523.                if (sscanf(p, "%d", &maxdrift)==0 || maxdrift<0)
  524.                   error("! Bad maxdrift option (-e).") ;
  525.                vmaxdrift = maxdrift;
  526.                break ;
  527. case 'f' :
  528.                filter = (*p != '0') ;
  529.                if (filter)
  530.                   oname = "" ;
  531.                noenv = 1 ;
  532.                sendcontrolD = 0 ;
  533.                break ;
  534. case 'h' : case 'H' :
  535.                if (*p == 0 && argv[i+1])
  536.                   p = argv[++i] ;
  537.                if (strcmp(p, "-") == 0)
  538.                   headers_off = 1 ;
  539.                else
  540.                   (void)add_header(p) ;
  541.                break ;
  542. case 'i':
  543.                sepfiles = (*p != '0') ;
  544.                break ;
  545. case 'k':
  546.                cropmarks = (*p != '0') ;
  547.                break ;
  548. case 'R':
  549.                secure = 1 ;
  550.                break ;
  551. case 'S':
  552.                if (*p == 0 && argv[i+1])
  553.                   p = argv[++i] ;
  554.                if (sscanf(p, "%d", &maxsecsize)==0)
  555.                   error("! Bad section size arg (-S).") ;
  556.                break ;
  557. case 'm' :
  558.                manualfeed = (*p != '0') ;
  559.                break ;
  560. case 'n' :
  561.                if (*p == 0 && argv[i+1])
  562.                   p = argv[++i] ;
  563. #ifdef SHORTINT
  564.                if (sscanf(p, "%ld", &maxpages)==0)
  565. #else        /* ~SHORTINT */
  566.                if (sscanf(p, "%d", &maxpages)==0)
  567. #endif        /* ~SHORTINT */
  568.                   error("! Bad number of pages option (-n).") ;
  569.                break ;
  570. case 'o' :
  571.                if (*p == 0 && argv[i+1] && *argv[i+1]!='-')
  572.                   p = argv[++i] ;
  573.                oname = p ;
  574.                noenv = 1 ;
  575.                sendcontrolD = 0 ;
  576.                break ;
  577. case 'O' :
  578.                if (*p == 0 && argv[i+1])
  579.                   p = argv[++i] ;
  580.                handlepapersize(p, &hoff, &voff) ;
  581.                break ;
  582. case 'T' :
  583.                if (*p == 0 && argv[i+1])
  584.                   p = argv[++i] ;
  585.                handlepapersize(p, &hpapersize, &vpapersize) ;
  586.                if (landscape) {
  587.                   error(
  588.               "both landscape and papersize specified; ignoring landscape") ;
  589.                   landscape = 0 ;
  590.                }
  591.                break ;
  592. case 'p' :
  593. #if defined MSDOS || defined OS2
  594.                /* check for emTeX job file (-pj=filename) */
  595.                if (*p == 'j') {
  596.                  p++;
  597.                  if (*p == '=')
  598.                    p++;
  599.                  mfjobname = newstring(p);
  600.                  break;
  601.                }
  602.                /* must be page number instead */
  603. #endif
  604.                if (*p == 'p') {  /* a -pp specifier for a page list? */
  605.                   p++ ;
  606.                   if (*p == 0 && argv[i+1])
  607.                      p = argv[++i] ;
  608.                   if (ParsePages(p))
  609.                      error("! Bad page list specifier (-pp).") ;
  610.                   pagelist = 1 ;
  611.                   break ;
  612.                }
  613.                if (*p == 0 && argv[i+1])
  614.                   p = argv[++i] ;
  615.                if (*p == '=') {
  616.                   abspage = 1 ;
  617.                   p++ ;
  618.                }
  619. #ifdef SHORTINT
  620.                switch(sscanf(p, "%ld.%ld", &firstpage, &firstseq)) {
  621. #else        /* ~SHORTINT */
  622.                switch(sscanf(p, "%d.%d", &firstpage, &firstseq)) {
  623. #endif        /* ~SHORTINT */
  624. case 1:           firstseq = 0 ;
  625. case 2:           break ;
  626. default:
  627.                   error("! Bad first page option (-p).") ;
  628.                }
  629.                notfirst = 1 ;
  630.                break ;
  631. case 'l':
  632.                if (*p == 0 && argv[i+1])
  633.                   p = argv[++i] ;
  634.                if (*p == '=') {
  635.                   abspage = 1 ;
  636.                   p++ ;
  637.                }
  638. #ifdef SHORTINT
  639.                switch(sscanf(p, "%ld.%ld", &lastpage, &lastseq)) {
  640. #else        /* ~SHORTINT */
  641.                switch(sscanf(p, "%d.%d", &lastpage, &lastseq)) {
  642. #endif        /* ~SHORTINT */
  643. case 1:           lastseq = 0 ;
  644. case 2:           break ;
  645. default:
  646.                   error("! Bad last page option (-p).") ;
  647.                }
  648.                notlast = 1 ;
  649.                break ;
  650. case 'A':
  651.                oddpages = 1 ;
  652.                break ;
  653. case 'B':
  654.                evenpages = 1 ;
  655.                break ;
  656. case 'q' : case 'Q' :
  657.                quiet = (*p != '0') ;
  658.                break ;
  659. case 'r' :
  660.                reverse = (*p != '0') ;
  661.                break ;
  662. case 't' :
  663.                if (*p == 0 && argv[i+1])
  664.                   p = argv[++i] ;
  665.                if (strcmp(p, "landscape") == 0) {
  666.                   if (hpapersize || vpapersize)
  667.                      error(
  668.              "both landscape and papersize specified; ignoring landscape") ;
  669.                   else
  670.                      landscape = 1 ;
  671.                } else
  672.                   paperfmt = p ;
  673.                break ;
  674. case 'x' : case 'y' :
  675.                if (*p == 0 && argv[i+1])
  676.                   p = argv[++i] ;
  677.                if (sscanf(p, "%d", &mag)==0 || mag < 10 ||
  678.                           mag > 100000)
  679.                   error("! Bad magnification parameter (-x).") ;
  680.                overridemag = (c == 'x' ? 1 : -1) ;
  681.                break ;
  682. case 'C' :
  683.                if (*p == 0 && argv[i+1])
  684.                   p = argv[++i] ;
  685.                if (sscanf(p, "%d", &collatedcopies)==0)
  686.                   error("! Bad number of collated copies option (-C).") ;
  687.                break ;
  688. case 'D' :
  689.                if (*p == 0 && argv[i+1])
  690.                   p = argv[++i] ;
  691.                if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
  692.                           actualdpi > 10000)
  693.                   error("! Bad dpi parameter (-D).") ;
  694.                vactualdpi = actualdpi;
  695.                break ;
  696. case 'E' :
  697.                tryepsf = (*p != '0') ;
  698.                break ;
  699. case 'K' :
  700.                removecomments = (*p != '0') ;
  701.                break ;
  702. case 'U' :
  703.                nosmallchars = (*p != '0') ;
  704.                break ;
  705. case 'X' :
  706.                if (*p == 0 && argv[i+1])
  707.                   p = argv[++i] ;
  708.                if (sscanf(p, "%d", &actualdpi)==0 || actualdpi < 10 ||
  709.                           actualdpi > 10000)
  710.                   error("! Bad dpi parameter (-D).") ;
  711.                break ;
  712. case 'Y' :
  713.                if (*p == 0 && argv[i+1])
  714.                   p = argv[++i] ;
  715.                if (sscanf(p, "%d", &vactualdpi)==0 || vactualdpi < 10 ||
  716.                           vactualdpi > 10000)
  717.                   error("! Bad dpi parameter (-D).") ;
  718.                vactualdpi = vactualdpi;
  719.                break ;
  720. case 'F' :
  721.                sendcontrolD = (*p != '0') ;
  722.                break ;
  723. case 'M':
  724.                dontmakefont = (*p != '0') ;
  725.                break ;
  726. case 'N' :
  727.                disablecomments = (*p != '0') ;
  728.                break ;
  729. case 'P' :
  730.                if (*p == 0 && argv[i+1])
  731.                   p = argv[++i] ;
  732.                printer = p ;
  733.                noenv = 1 ;
  734.                getdefaults("") ;
  735.                break ;
  736. case 's' :
  737.                safetyenclose = (*p != '0') ;
  738.                break ;
  739. case 'Z' :
  740.                compressed = (*p != '0') ;
  741.                break ;
  742. case '?' :
  743.                (void)fprintf(stderr, banner) ;
  744.                help() ;
  745.                break ;
  746. default:
  747.                error(
  748.               "! Bad option, not one of acdefhiklmnopqrstxCDEFKMNOPSTUXYZ?") ;
  749.             }
  750.          } else {
  751.             if (*iname == 0) {
  752.                register char *p ;
  753.    
  754.                lastext = 0 ;
  755.                iname = nextstring ;
  756.                p = argv[i] ;
  757.                while (*p) {
  758.                   *nextstring = *p++ ;
  759.                   if (*nextstring == '.')
  760.                      lastext = nextstring - iname ;
  761.                   else if (*nextstring == '/' || *nextstring == ':')
  762.                      lastext = 0 ;
  763.                   nextstring++ ;
  764.                }
  765.                *nextstring++ = '.' ;
  766.                *nextstring++ = 'd' ;
  767.                *nextstring++ = 'v' ;
  768.                *nextstring++ = 'i' ;
  769.                *nextstring++ = 0 ;
  770.             } else
  771.                error("! Two input file names specified.") ;
  772.          }
  773.       }
  774.       if (noenv == 0) {
  775.          register char *p ;
  776.          extern char *getenv() ;
  777.          if (0 != (p = getenv("PRINTER"))) {
  778. #ifdef OS2
  779.             strcpy(nextstring, p) ;
  780.             strcat(nextstring, ".cfg") ;
  781. #else
  782.             strcpy(nextstring, "config.") ;
  783.             strcat(nextstring, p) ;
  784. #endif
  785.             getdefaults(nextstring) ;
  786.          }
  787.       }
  788.       if (queryoptions != 0) {            /* get new options */
  789.          (void)fprintf(stderr, banner) ;
  790.          help() ;
  791.          queryargs();
  792.          if (qargc == 1)
  793.            queryoptions = 0;
  794.          else {
  795.            qargv[0] = argv[0];
  796.            argc=qargc;
  797.            argv=qargv;
  798.          }
  799.       }
  800.    } while (queryoptions != 0) ;
  801. #endif
  802.    checkenv(1) ;
  803. /*
  804.  *   The logic here is a bit convoluted.  Since all `additional'
  805.  *   PostScript font information files are loaded *before* the master
  806.  *   one, and yet they should be able to override the master one, we
  807.  *   have to add the information in the master list to the *ends* of
  808.  *   the hash chain.  We do this by reversing the lists, adding them
  809.  *   to the front, and then reversing them again.
  810.  */
  811.    revpslists() ;
  812.    getpsinfo((char *)NULL) ;
  813.    revpslists() ;
  814.    if (!quiet)
  815.       (void)fprintf(stderr, banner) ;
  816.    if (*iname) {
  817.       dvifile = fopen(iname, READBIN) ;
  818. /*
  819.  *   Allow names like a.b.
  820.  */
  821.       if (dvifile == 0) {
  822.          iname[strlen(iname)-4] = 0 ; /* remove the .dvi suffix */
  823.          dvifile = fopen(iname, READBIN) ;
  824.       }
  825.    }
  826.    if (oname[0] == '-' && oname[1] == 0)
  827.       oname[0] = 0 ;
  828.    if (*oname == 0 && ! filter) {
  829.       oname = nextstring ;
  830. #ifndef VMCMS  /* get stuff before LAST "." */
  831.       lastext = strlen(iname) - 1 ;
  832.       while (iname[lastext] != '.' && lastext > 0)
  833.          lastext-- ;
  834.       if (iname[lastext] != '.')
  835.          lastext = strlen(iname) - 1 ;
  836. #else   /* for VM/CMS we take the stuff before FIRST "." */
  837.       lastext = strchr(iname,'.') - iname ;
  838.       if ( lastext <= 0 )     /* if no '.' in "iname" */
  839.          lastext = strlen(iname) -1 ;
  840. #endif
  841. #ifdef MVSXA /* IBM: MVS/XA */
  842.       if (strchr(iname, '(') != NULL  &&
  843.           strchr(iname, ')') != NULL) {
  844.       firstext = strchr(iname, '(') - iname + 1;
  845.       lastext = strrchr(iname, ')') - iname - 1;
  846.          }
  847.       else {
  848.       if (strrchr(iname, '.') != NULL) {
  849.       lastext = strrchr(iname, '.') - iname - 1;
  850.            }
  851.          else lastext = strlen(iname) - 1 ;
  852.       if (strchr(iname, '\'') != NULL)
  853.          firstext = strchr(iname, '.') - iname + 1;
  854.          else firstext = 0;
  855.       }
  856. #endif  /* IBM: MVS/XA */
  857. #ifdef MVSXA /* IBM: MVS/XA */
  858.       for (i=firstext; i<=lastext; i++)
  859. #else
  860.       for (i=0; i<=lastext; i++)
  861. #endif
  862.          *nextstring++ = iname[i] ;
  863.       if (iname[lastext] != '.')
  864.          *nextstring++ = '.' ;
  865. #ifndef VMCMS
  866.       *nextstring++ = 'p' ;
  867.       *nextstring++ = 's' ;
  868. #else  /* might as well keep things uppercase */
  869.       *nextstring++ = 'P' ;
  870.       *nextstring++ = 'S' ;
  871. #endif
  872.       *nextstring++ = 0 ;
  873. /*
  874.  *   Now we check the name, and `throw away' any prefix information.
  875.  *   This means throwing away anything before (and including) a colon
  876.  *   or slash.
  877.  */
  878.       {
  879.          char *p ;
  880.  
  881.          for (p=oname; *p && p[1]; p++)
  882.             if (*p == ':' || *p == DIRSEP)
  883.                oname = p + 1 ;
  884.       }
  885.    }
  886. #ifdef DEBUG
  887.    if (dd(D_PATHS)) {
  888. #ifdef SHORTINT
  889.         (void)fprintf(stderr,"input file %s output file %s swmem %ld\n",
  890. #else /* ~SHORTINT */
  891.            (void)fprintf(stderr,"input file %s output file %s swmem %d\n",
  892. #endif /* ~SHORTINT */
  893.            iname, oname, swmem) ;
  894.    (void)fprintf(stderr,"tfm path %s\npk path %s\n", tfmpath, pkpath) ;
  895.    (void)fprintf(stderr,"fig path %s\nvf path %s\n", figpath, vfpath) ;
  896.    (void)fprintf(stderr,"config path %s\nheader path %s\n",
  897.                   configpath, headerpath) ;
  898. #ifdef FONTLIB
  899.    (void)fprintf(stderr,"fli path %s\nfli names %s\n", flipath, fliname) ;
  900. #endif
  901.    } /* dd(D_PATHS) */
  902. #endif /* DEBUG */
  903. /*
  904.  *   Now we try to open the dvi file.
  905.  */
  906.    if (warningmsg)
  907.       error(warningmsg) ;
  908.    headersready = 1 ;
  909.    headerfile = (compressed? CHEADERFILE : HEADERFILE) ;
  910.    (void)add_header(headerfile) ;
  911.    if (*iname != 0) {
  912.       fulliname = nextstring ;
  913. #ifndef IGNORE_CWD
  914.       if (*iname != '/') {
  915.         getcwd(nextstring, MAXPATHLEN + 2);
  916.         while (*nextstring++) ;
  917. #ifdef VMS        /* VMS doesn't need the '/' character appended */
  918.         nextstring--;    /* so just back up one byte. */
  919. #else
  920.         *(nextstring-1) = '/' ;
  921. #endif
  922.       }
  923. #endif
  924.       strcpy(nextstring,iname) ;
  925.       while (*nextstring++) ; /* advance nextstring past fulliname */
  926.    } else if (filter)
  927.       dvifile = stdin;
  928.    else {
  929.       help() ;
  930.       exit(0) ;
  931.    }
  932.    initcolor() ;
  933.    if (dvifile==NULL) {
  934.       extern char errbuf[];
  935.       (void)sprintf(errbuf,"! DVI file <%s> can't be opened.", iname) ;
  936.       error("! DVI file can't be opened.") ;
  937.    }
  938.    if (fseek(dvifile, 0L, 0) < 0)
  939.       error("! DVI file must not be a pipe.") ;
  940. #ifdef FONTLIB
  941.    fliload();    /* read the font libaries */
  942. #endif
  943. /*
  944.  *   Now we do our main work.
  945.  */
  946.    swmem += fontmem ;
  947.    if (maxdrift < 0) {
  948.       if (actualdpi <= 599)
  949.          maxdrift = actualdpi / 100 ;
  950.       else if (actualdpi < 1199)
  951.          maxdrift = actualdpi / 200 + 3 ;
  952.       else
  953.          maxdrift = actualdpi / 400 + 6 ;
  954.    }
  955.    if (vmaxdrift < 0) {
  956.       if (vactualdpi <= 599)
  957.          vmaxdrift = vactualdpi / 100 ;
  958.       else if (vactualdpi < 1199)
  959.          vmaxdrift = vactualdpi / 200 + 3 ;
  960.       else
  961.          vmaxdrift = vactualdpi / 400 + 6 ;
  962.    }
  963.    if (dopprescan)
  964.       pprescanpages() ;
  965.    prescanpages() ;
  966. #if defined MSDOS || defined OS2
  967.    if (mfjobfile != (FILE*)NULL) {
  968.      char answer[5];
  969.      fputs("}\n",mfjobfile);
  970.      fclose(mfjobfile);
  971.      fputs("Exit to make missing fonts now (y/n)? ",stdout);
  972.      fgets(answer,4,stdin);
  973.      if (*answer=='y' || *answer=='Y')
  974.        exit(8); /* exit with errorlevel 8 for emTeX dvidrv */
  975.    }
  976. #endif
  977.    if (includesfonts)
  978.       (void)add_header(IFONTHEADER) ;
  979.    if (usesPSfonts)
  980.       (void)add_header(PSFONTHEADER) ;
  981.    if (usesspecial)
  982.       (void)add_header(SPECIALHEADER) ;
  983.    if (usescolor)  /* IBM: color */
  984.       (void)add_header(COLORHEADER) ;
  985.    papsizes = (struct papsiz *)revlist((void *)papsizes) ;
  986.    sects = sections ;
  987.    totalpages *= collatedcopies ;
  988.    if (sects == NULL || sects->next == NULL) {
  989.       sectioncopies = collatedcopies ;
  990.       collatedcopies = 1 ;
  991.    } else {
  992.       if (! sepfiles)
  993.          multiplesects = 1 ;
  994.    }
  995.    totalpages *= pagecopies ;
  996.    if (tryepsf) {
  997.       if (totalpages != 1 || paperfmt || landscape || manualfeed ||
  998.           collatedcopies > 1 || numcopies > 1 || cropmarks ||
  999.           *iname == 0) {
  1000.          error("Can't make it EPSF, sorry") ;
  1001.          tryepsf = 0 ;
  1002.       }
  1003.    }
  1004.    if (! sepfiles) {
  1005.       initprinter(0) ;
  1006.       outbangspecials() ;
  1007.    }
  1008.    for (i=0; i<collatedcopies; i++) {
  1009.       sects = sections ;
  1010.       while (sects != NULL) {
  1011.          if (sepfiles) {
  1012.             newoutname() ;
  1013.             if (! quiet) {
  1014.                if (prettycolumn + strlen(oname) + 6 > STDOUTSIZE) {
  1015.                   fprintf(stderr, "\n") ;
  1016.                   prettycolumn = 0 ;
  1017.                }
  1018.                (void)fprintf(stderr, "(-> %s) ", oname) ;
  1019.                prettycolumn += strlen(oname) + 6 ;
  1020.             }
  1021.             initprinter(sects->numpages) ;
  1022.             outbangspecials() ;
  1023.          } else if (! quiet) {
  1024.             if (prettycolumn > STDOUTSIZE) {
  1025.                fprintf(stderr, "\n") ;
  1026.                prettycolumn = 0 ;
  1027.             }
  1028.             (void)fprintf(stderr, ". ") ;
  1029.             prettycolumn += 2 ;
  1030.          }
  1031.          (void)fflush(stderr) ;
  1032.          dosection(sects, sectioncopies) ;
  1033.          sects = sects->next ;
  1034.          if (sepfiles)
  1035.             cleanprinter() ;
  1036.       }
  1037.    }
  1038.    if (! sepfiles)
  1039.       cleanprinter() ;
  1040.    if (! quiet)
  1041.       (void)fprintf(stderr, "\n") ;
  1042. #ifdef DEBUG
  1043.    if (dd(D_MEM)) {
  1044. #ifdef SHORTINT
  1045.       fprintf(stderr, "Total memory allocated:  %ld\n", totalalloc) ;
  1046. #else
  1047.       fprintf(stderr, "Total memory allocated:  %d\n", totalalloc) ;
  1048. #endif
  1049.    }
  1050. #endif
  1051.    exit(0) ;
  1052.    /*NOTREACHED*/
  1053. }
  1054. #ifdef VMS
  1055. #include "[]vmscli.c"
  1056. #endif
  1057.  
  1058. #ifdef VMCMS  /* IBM: VM/CMS */
  1059. #include "dvipscms.h"
  1060. #endif
  1061.  
  1062. #ifdef MVSXA  /* IBM: MVS/XA */
  1063. #include "dvipsmvs.h"
  1064. #endif
  1065.